/*
 * classe responsavel por controlar o tabuleiro do cliente.
 * 
 * obs.: - atualmente só controla um tabuleiro por vez, na ideia de que para cada tabuleiro
 * exista um controlador
 *       - a Telajogo apenas exibe as informações,sendo todas as decisões tomadas pelo controlador 
 * 
 */
package client.controller;

import client.model.Jogador;
import client.model.Tabuleiro;
import java.awt.Point;
import java.net.UnknownHostException;
import view.MapeiaTabuleiro;
import view.TelaJogo;



public class TabuleiroController {
    private Tabuleiro tabuleiro;
    private MapeiaTabuleiro mapaTab = MapeiaTabuleiro.getInstance();
    private CalculoPosicao calculoPos;
    private TelaJogo jogo;
    private int numJogador;  // guarda o número do jogador no tabuleiro
    private Jogador jogador; // guarda informações sobre o jogador cliente (que está jogando no programa host)
    private int numJogada = 0; // armazena o número da jogad, sendo incrementado a cada turno
    private boolean salaCheia;
    
    /*
     * nesse metodo é necessário:
     *  - obter o número do jogador, pois o número do jogador varia de acordo com o jogo que o usuário quer se conectar
     */
    public TabuleiroController() {
        salaCheia = false;
        calculoPos = new CalculoPosicao();
    }
    
    public void iniciaJogo(boolean isServer) throws UnknownHostException{
        
        tabuleiro = new Tabuleiro(isServer);
        jogador = tabuleiro.getJogador();
        this.numJogador = jogador.getNum();
        jogo = new TelaJogo(this, this.numJogador, 10); 
        if(numJogador == 1){//jogador 1 é o primeiro
            jogo.habilitarEventos();
            jogo.iniciarTemporizador();
        }
        jogo.setVisible(true);
    }
    
    public void setSalaCheia(boolean salaCheia){
        this.salaCheia = salaCheia;
    }
    
    public boolean getSalaCheia(){
        return salaCheia;
    }
    
    public String criaStatus(){
        String status;
        status = "STA:".concat(jogador.getNome().concat(":"));
        return status;
    }
    
    public void setNumJod(int n){
        tabuleiro.getJogador().setNum(n);
    }
    
    // Move o peão de acordo com a posição e o valor do dado. Também faz consulta no estado 
    // do jogo se o peão pode ser movido ou não(caso tenha um castelo na frente, por exemplo)
    public boolean getIsServer(){
        return jogador.getServer();
    }
    
    public void addJogador(String nome, int num){
        tabuleiro.setJogador(nome, num);
    }
    
    public void moverPeao(int numPeao, int valorDado){
        Point p;
        int nPeoes;
        
        switch(valorDado){
            case 1:
                if(jogador.peaoNaBase(numPeao)){
                    p = calculoPos.calculoBaseParaTabuleiro(numJogador);
                    nPeoes = verificaPeoesNaCasa(p);
                    if(nPeoes != 0){
                        jogo.setCasteloPeao(numJogador, numPeao, nPeoes+1);
                    }
                    jogo.moverPeao(numJogador, numPeao, mapaTab.getPontoFigura(p.x, p.y));
                    jogador.setPosPeao(numPeao, p);
                    jogador.setPeaoNaBase(numPeao, false); // tira peão da base*/            
                }
                else {
                    if(calculoPos.verificaFaixaSeguranca(jogador.getPosPeao(numPeao))){
                        p = calculoPos.calculoBaseParaTabuleiro(numJogador);
                    }
                }
                //jogo.desabilitarEventos();
                break;
                
            case 2:
                if(jogador.peaoNaBase(numPeao)){
                    break;  // caso tire 2 e o peão estiver na base, não faz nada (sai do laço)
                }
                else {
                    p = calculoPos.calculo(numJogador, jogador.getPosPeao(numPeao), valorDado);
                    jogo.moverPeao(numJogador, numPeao, mapaTab.getPontoFigura(p.x, p.y));
                    jogador.setPosPeao(numPeao, p);
                }
                //jogo.desabilitarEventos();
                break;
                
            case 3:
                if(jogador.peaoNaBase(numPeao)){
                    break;  // caso tire 3 e o peão estiver na base, não faz nada (sai do laço)
                }
                else {
                    p = calculoPos.calculo(numJogador, jogador.getPosPeao(numPeao), valorDado);
                    jogo.moverPeao(numJogador, numPeao, mapaTab.getPontoFigura(p.x, p.y));
                    jogador.setPosPeao(numPeao, p);
                }
                //jogo.desabilitarEventos();
                break; 
                
            case 4:
                if(jogador.peaoNaBase(numPeao)){
                    break;  // caso tire 4 e o peão estiver na base, não faz nada (sai do laço)
                }
                else {
                    p = calculoPos.calculo(numJogador, jogador.getPosPeao(numPeao), valorDado);
                    jogo.moverPeao(numJogador, numPeao, mapaTab.getPontoFigura(p.x, p.y));
                    jogador.setPosPeao(numPeao, p);
                }
                //jogo.desabilitarEventos();
                break;
                
            case 5:
                if(jogador.peaoNaBase(numPeao)){
                    break;  // caso tire 5 e o peão estiver na base, não faz nada (sai do laço)
                }
                else {
                    p = calculoPos.calculo(numJogador, jogador.getPosPeao(numPeao), valorDado);
                    jogo.moverPeao(numJogador, numPeao, mapaTab.getPontoFigura(p.x, p.y));
                    jogador.setPosPeao(numPeao, p);
                }
                //jogo.desabilitarEventos();
                break;
            
            case 6:
                if(jogador.peaoNaBase(numPeao)){
                    p = calculoPos.calculoBaseParaTabuleiro(numJogador);
                    jogo.moverPeao(numJogador, numPeao, mapaTab.getPontoFigura(p.x, p.y));
                    jogador.setPosPeao(numPeao, p);
                    jogador.setPeaoNaBase(numPeao, false); // tira peão da base
                }
                //jogo.habilitarEventos();
                break;    
        }
    }
    
    // verifica e retorna o número existente (0 a 4) de peões na casa passada pelo argumento
    public int verificaPeoesNaCasa(Point p){
        int n = 0; // guarda número de peões existentes na casa
        
        for (int i = 1; i < 5; i++) {
            // se as posições forem iguais incrmenta n
            if(jogador.getPosPeao(i).equals(p)){
                n++;
            }
        }
        System.out.println("Peões na posição > "+n); // [teste]
        return n;
    }
    
    /* Método que retorna mensagem para barra de status, de acordo com o valor do dado.
     *
     * Obs.: - Falta retornar a sugestão para montar castelo
    */
    public String getStatus(int valorDado){
        switch(valorDado){
            case 1:
                // se todos os peões estão na base
                if(jogador.todosPeoesNaBase()){
                    return "Selecione um peão da base para ir para o tabuleiro.";
                }
                // se todos os peões estiverem no tabuleiro
                else if(jogador.todosPeoesNoTabuleiro()){
                    return "Escolha um peão para andar no tabuleiro.";
                }
                // se possuir peões no tabuleiro e na base
                else{
                    return "Escolha um peão da base ou do tabuleiro para andar.";
                }
                
            case 2:
                // se todos os peões estão na base
                if(jogador.todosPeoesNaBase()){
                    return "Passou a vez.";
                }
                // se todos os peões estiverem no tabuleiro
                else if(jogador.todosPeoesNoTabuleiro()){
                    return "Escolha um peão para andar no tabuleiro.";
                }
                // se possuir peões no tabuleiro e na base
                else{
                    return "Escolha um peão do tabuleiro para andar.";
                }
                
            case 3:
                // se todos os peões estão na base
                if(jogador.todosPeoesNaBase()){
                    return "Passou a vez.";
                }
                // se todos os peões estiverem no tabuleiro
                else if(jogador.todosPeoesNoTabuleiro()){
                    return "Escolha um peão para andar no tabuleiro.";
                }
                // se possuir peões no tabuleiro e na base
                else{
                    return "Escolha um peão do tabuleiro para andar.";
                }
                
            case 4:
                // se todos os peões estão na base
                if(jogador.todosPeoesNaBase()){
                    return "Passou a vez.";
                }
                // se todos os peões estiverem no tabuleiro
                else if(jogador.todosPeoesNoTabuleiro()){
                    return "Escolha um peão para andar no tabuleiro.";
                }
                // se possuir peões no tabuleiro e na base
                else{
                    return "Escolha um peão do tabuleiro para andar.";
                }
                
            case 5:
                // se todos os peões estão na base
                if(jogador.todosPeoesNaBase()){
                    return "Passou a vez.";
                }
                // se todos os peões estiverem no tabuleiro
                else if(jogador.todosPeoesNoTabuleiro()){
                    return "Escolha um peão para andar no tabuleiro.";
                }
                // se possuir peões no tabuleiro e na base
                else{
                    return "Escolha um peão do tabuleiro para andar.";
                }
            
            case 6:
                // se todos os peões estão na base
                if(jogador.todosPeoesNaBase()){
                    return "Selecione um peão da base para ir para o tabuleiro.";
                }
                // se todos os peões estiverem no tabuleiro
                else if(jogador.todosPeoesNoTabuleiro()){
                    return "Escolha um peão para andar no tabuleiro.";
                }
                // se possuir peões no tabuleiro e na base
                else{
                    return "Escolha um peão da base ou do tabuleiro para andar.";
                }
        }
        return " ";
    }
    
    public void desabilitarInterface(){
        jogo.desabilitarEventos();
    }
    
    public void habilitarInterface(){
        jogo.desabilitarEventos();
    }
    
    // chama temporizador na interface, para contar tempo que o jogador tem para jogar o dado e selecionar o peão
    public void contarTempo(){
        jogo.iniciarTemporizador();
    }
    
    // método chamado toda a vez que o jogador estoura seu tempo limite para jogar
    public void tempoLimiteAlcancado(){
        System.out.println("perdeu a jogada!");
    }
}
